#ifndef	__BFX_REF_XMLNODE_H__
#define	__BFX_REF_XMLNODE_H__

namespace BFX
{

//////////////////////////////////////////////////////////////////////////////

class REFXMLText;
class REFXMLAttribute;
class REFXMLCDataSection;
class REFXMLComment;
class REFXMLDeclaration;
class REFXMLDocument;
class REFXMLDocumentType;
class REFXMLElement;
class REFXMLEntity;
class REFXMLEntityReference;
class REFXMLLinkedNode;
class REFXMLNotation;
class REFXMLProcessingInstruction;
class REFXMLText;

class REFXMLNodeList;
class REFXMLNodeMap;
class REFXMLAttributeMap;

class REFXMLName;
class REFNameTable;
class REFXMLNameTable;
class REFXMLSchemaInfo;
class REFXMLSchemaElementDecl;
class REFXMLSchemaAttDef;

//////////////////////////////////////////////////////////////////////////////
// Represents a single node in the document.

class BFX_API REFXMLNode : public REFObject
{
	friend class REFXMLAttributeMap;
	friend class REFXMLNodeMap;
	friend class REFXMLText;
	friend class REFXMLCDataSection;
	friend class REFXMLLoader;
	friend class REFXMLElementList;

protected:
	REFXMLNode();
	REFXMLNode(REFXMLDocument* pDoc);
public:
	virtual ~REFXMLNode();

	// Gets the name of the node.
	virtual UniString GetName() const = 0;

	// Gets or sets the value of the node.
	virtual UniString GetValue() const;
	virtual void SetValue(const UniString& strValue);

	// Gets the namespace URI of this node.
	virtual UniString GetNamespaceURI() const;

	// Gets or sets the namespace prefix of this node.
	virtual UniString GetPrefix() const;
	virtual void SetPrefix(const UniString& str);

	// Gets the name of the node without the namespace prefix.
	virtual UniString GetLocalName() const	= 0;

	// Gets the type of the current node.
	virtual XMLNodeType GetNodeType() const	= 0;
	// Gets the parent of this node (for nodes that can have parents).
	virtual REFXMLNode* GetParentNode() const;

	// Gets all children of this node.
	virtual REFXMLNodeList* GetChildNodes() const;

	// Gets the node immediately preceding this node.
	virtual REFXMLNode* GetPreviousSibling() const;
	// Gets the node immediately following this node.
    virtual REFXMLNode* GetNextSibling() const;

	// Gets a collection containing the attributes of this node.
	virtual REFXMLAttributeMap* GetAttributes() const;
	// Gets the XmlDocument that contains this node.
	virtual REFXMLDocument* GetOwnerDocument() const;

	// Gets the first child of this node.
	virtual REFXMLNode* GetFirstChild() const;
	// Gets the last child of this node.
	virtual REFXMLNode* GetLastChild() const;

	// Inserts the specified node immediately before the specified reference node.
	virtual REFXMLNode* InsertBefore(REFXMLNode* pNewChild, const REFXMLNode* pRefChild);
	// Inserts the specified node immediately after the specified reference node.
	virtual REFXMLNode* InsertAfter(REFXMLNode* pNewChild, const REFXMLNode* pRefChild);

	// Replaces the child node oldChild with newChild node.
	virtual REFXMLNode* ReplaceChild(REFXMLNode* pNewChild, REFXMLNode* pOldChild);

	// Removes specified child node.
	virtual REFXMLNode* RemoveChild(REFXMLNode* pOldChild);

	// Adds the specified node to the beginning of the list of children of this node.
    virtual REFXMLNode* PrependChild(REFXMLNode* pNewChild);

	// Adds the specified node to the end of the list of children of this node.
	virtual REFXMLNode* AppendChild(REFXMLNode* pNewChild);

#if	0
	// Creates a duplicate of this node.
	virtual REFXMLNode* CloneNode(bool bDeep = true) const = 0;
#endif
	// Gets or sets the concatenated values of the node and all its children.
	virtual UniString GetInnerText() const;
	virtual void SetInnerText(const UniString& str);

	// Gets or sets the markup representing just the children of this node.
	virtual UniString GetInnerXml() const;
	virtual void SetInnerXml(const UniString& str);

	// Gets the markup representing this node and all its children.
	virtual UniString GetOuterXml() const;

	// Saves the current node to the specified XmlWriter.
	virtual void WriteTo(REFXMLWriter* w) const = 0;

	virtual UniString GetBaseURI() const;

	// Saves all the children of the node to the specified XmlWriter.
	virtual  void WriteContentTo(REFXMLWriter* w) const = 0;

	// Removes all the children and/or attributes of the current node.
	virtual void RemoveAll();

protected:
	virtual void SetParent(REFXMLNode* pNode);

	virtual bool IsContainer() const;
	virtual bool IsValidChildType(XMLNodeType type) const;
	virtual bool IsText() const;
	virtual REFXMLNode* GetPreviousText() const;

	bool AncestorNode(REFXMLNode* pNode) const;

	virtual REFXMLLinkedNode* GetFirstNode() const;
	virtual void SetFirstNode(REFXMLLinkedNode* pNode);

	virtual REFXMLLinkedNode* GetLastNode() const;
	virtual void SetLastNode(REFXMLLinkedNode* pNode);

	virtual REFXMLNode* FindChild(XMLNodeType type) const;

	//the function is provided only at Load time to speed up Load process
	virtual REFXMLNode* AppendChildForLoad(REFXMLNode* pNewChild, REFXMLDocument* pDoc);
	virtual void SetParentForLoad(REFXMLNode* pNode);

	void AppendChildText(INOUT UniString& strBuilder) const;
	REFXMLDocument* GetDocument() const;

	// trace to the top to find out its parent node.
	bool IsConnected() const;

	static void SplitName(const UniString& strName, OUT UniString& strPrefix, OUT UniString& strLocalName);
	static void NestTextNodes(REFXMLNode* pPrevNode, REFXMLNode* pNextNode);
	static void UnnestTextNodes(REFXMLNode* pPrevNode, REFXMLNode* pNextNode);

protected:
	 //this pointer is reused to save the userdata information, need to prevent internal user access the pointer directly.
	REFXMLNode*	m_pParentNode;
};

}	//	namespace BFX

#endif	//	__BFX_REF_XMLNODE_H__
